﻿using AForge.Video.DirectShow;
using AJWPFAdmin.Core.Components.AJFilePicker.ViewModels;
using AJWPFAdmin.Core.Components.ViewModels;
using AJWPFAdmin.Core.Utils;
using DocumentFormat.OpenXml.InkML;
using Masuit.Tools.Systems;
using Microsoft.Win32;
using Prism.Ioc;
using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace AJWPFAdmin.Core.Components.Views
{
    /// <summary>
    /// AJFilePicker.xaml 的交互逻辑
    /// </summary>
    public partial class AJFilePicker : UserControl
    {

        public static DependencyProperty DisplayOnlyProperty =
            DependencyProperty.Register(nameof(DisplayOnly), typeof(bool), typeof(AJFilePicker), new PropertyMetadata(false, DisplayOnlyPropertyChanged));

        public bool DisplayOnly
        {
            get { return (bool)GetValue(DisplayOnlyProperty); }
            set { SetValue(DisplayOnlyProperty, value); }
        }

        private static void DisplayOnlyPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            if (sender is AJFilePicker picker)
            {
                picker.UpdateComponent();
            }
        }


        public static DependencyProperty ImagesProperty =
            DependencyProperty.Register(nameof(Images), typeof(ObservableCollection<UploadFileItem>), typeof(AJFilePicker), new PropertyMetadata(new ObservableCollection<UploadFileItem>(), ImagesPropertyChanged));

        public ObservableCollection<UploadFileItem> Images
        {
            get { return (ObservableCollection<UploadFileItem>)GetValue(ImagesProperty); }
            set { SetValue(ImagesProperty, value); }
        }

        private static void ImagesPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            if (sender is AJFilePicker picker)
            {
                picker.UpdateComponent();
            }
        }


        public static DependencyProperty OptionsProperty =
            DependencyProperty.Register(nameof(Options), typeof(UploadConfig), typeof(AJFilePicker), new PropertyMetadata(UploadConfig.Default, OptionsPropertyChanged));

        public UploadConfig Options
        {
            get { return (UploadConfig)GetValue(OptionsProperty); }
            set { SetValue(OptionsProperty, value); }
        }

        private static void OptionsPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            if (sender is AJFilePicker picker)
            {
                picker.UpdateComponent();
            }
        }

        private static readonly string _uploadFolder = System.IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(), "uploads");

        private string _monikerString;

        private IDialogService _dialogSvc;

        public AJFilePicker()
        {
            InitializeComponent();
            Images ??= new ObservableCollection<UploadFileItem>();
            UpdateComponent();
            _dialogSvc = Prism.Ioc.ContainerLocator.Current.Resolve<IDialogService>();
            Task.Run(() =>
            {
                var videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
                if (videoDevices?.Count > 0)
                {
                    _monikerString = videoDevices[0].MonikerString;
                }
            });
        }

        private void UpdateComponent()
        {
            Btn_Upload.Width = Options.Width;
            Btn_Upload.Height = Options.Height;
            Btn_Upload.Content = Options.Text;
            if (Images?.Count > 0)
            {
                foreach (var item in Images)
                {
                    item.CanDelete = DisplayOnly ? Visibility.Collapsed : Visibility.Visible;
                    item.DisplayHeight = Btn_Upload.Height;
                    item.DisplayWidth = Btn_Upload.Width;
                }
            }

            RaiseUploadBtnVisibleChange();
        }

        private async void Btn_Upload_Click(object sender, RoutedEventArgs e)
        {
            if (false == Options.BeforeFileDialogShowHandle?.Invoke(this))
            {
                return;
            }

            if (Options.ManualUpload)
            {
                return;
            }

            ConfirmUpload();
        }

        public async void ConfirmUpload()
        {
            var targetDir = !string.IsNullOrWhiteSpace(Options.CustomUploadFolder) 
                ? Options.CustomUploadFolder
                : System.IO.Path.Combine(_uploadFolder, "images");

            try
            {
                if (!Directory.Exists(targetDir))
                {
                    Directory.CreateDirectory(targetDir);
                }
            }
            catch (Exception e)
            {
                MessageBox.Show($"创建上传目录失败,请检查文件权限:{e.Message}");
                return;
            }
            

            if (!string.IsNullOrWhiteSpace(_monikerString))
            {
                if (MessageBox.Show("是否使用摄像头", "当前支持摄像头拍照", MessageBoxButton.YesNo)
                    == MessageBoxResult.Yes)
                {
                    var @params = new DialogParameters
                    {
                        { "data", _monikerString },
                    };
                    _dialogSvc.ShowDialog(nameof(USBCameraPreviewer), @params,
                        (r) =>
                        {
                            if (r.Result == ButtonResult.OK)
                            {
                                r.Parameters.TryGetValue<BitmapFrame>("data", out var frame);
                                if (frame != null)
                                {
                                    var fName = Options.CustomerFileNameHandle != null
                    ? $"{Options.CustomerFileNameHandle()}.jpg" : $"{SnowFlake.GetInstance().GetUniqueShortId()}_capture.jpg";
                                    var temp = System.IO.Path.Combine(targetDir, fName);

                                    try
                                    {
                                        using var fileStream = new FileStream(temp, FileMode.OpenOrCreate);
                                        var encoder = new JpegBitmapEncoder();
                                        encoder.Frames.Add(frame);
                                        encoder.Save(fileStream);
                                    }
                                    catch (Exception e)
                                    {
                                        MessageBox.Show(e.Message, "上传失败", MessageBoxButton.OK);
                                        return;
                                    }
                                    var item = new UploadFileItem(temp)
                                    {
                                        DisplayWidth = Options.Width,
                                        DisplayHeight = Options.Height,
                                    };
                                    Images.Add(item);
                                    RaiseUploadBtnVisibleChange();
                                }
                            }
                        });
                    return;
                }
            }

            var dialog = new OpenFileDialog
            {
                Filter = Options.Filters
            };

            if (dialog.ShowDialog().GetValueOrDefault())
            {
                var fName = Options.CustomerFileNameHandle != null
                    ? $"{Options.CustomerFileNameHandle()}{System.IO.Path.GetExtension(dialog.FileName)}" 
                    : $"{SnowFlake.GetInstance().GetUniqueShortId()}_{System.IO.Path.GetFileName(dialog.FileName)}";
                var temp = System.IO.Path.Combine(targetDir, fName);
                var success = await Task.Run(() =>
                {
                    return CommonUtil.CopyFile(dialog.FileName, temp);
                });

                var item = new UploadFileItem(temp)
                {
                    DisplayWidth = Options.Width,
                    DisplayHeight = Options.Height,
                };
                Images.Add(item);

                RaiseUploadBtnVisibleChange();

                if (!success)
                {
                    Images.Remove(item);
                    RaiseUploadBtnVisibleChange();
                    AJCommonDialog.ShowDialog(new AJCommonDialogViewModel.AJCommonDialogParams
                    {
                        Title = "上传失败!",
                        Message = "请确认文件读写权限或文件是否存在",
                    });
                }

            }
        }

        private void RaiseUploadBtnVisibleChange()
        {
            Btn_Upload.Visibility = !DisplayOnly
                ? (Images?.Count).GetValueOrDefault() < Options.Limit ? Visibility.Visible : Visibility.Collapsed
                : Visibility.Collapsed;

            Border_ItemBorder.Visibility = DisplayOnly && (Images?.Count).GetValueOrDefault() == 0
                ? Visibility.Visible : Visibility.Collapsed;

        }

        private async void Btn_Delete_Click(object sender, RoutedEventArgs e)
        {
            var ret = await CommonUtil.ShowConfirmDialogAsync(new MaterialDesignExtensions.Controls.ConfirmationDialogArguments
            {
                Title = $"确定删除该图片吗?"
            });

            if (ret)
            {
                var item = ((Button)sender).DataContext as UploadFileItem;
                item.Loading = Visibility.Visible;

                // 如果删除的是系统破图/或者网络图， 那直接通过逻辑，不要实际删除文件 
                if ("media-empty.png".Equals(System.IO.Path.GetFileName(item.Url))
                    || CommonRegex.HTTPURLREGEX.IsMatch(item.Url))
                {
                    await Task.Delay(800);
                }
                else
                {
                    var url = item.Url;
                    await Task.Delay(1000);
                    await Task.Run(() =>
                    {
                        try
                        {
                            File.Delete(url);
                        }
                        catch
                        {

                        }
                    });
                }

                Images.Remove(item);

                item.Loading = Visibility.Collapsed;

                RaiseUploadBtnVisibleChange();
            }
        }

        private void Btn_PreView_Click(object sender, RoutedEventArgs e)
        {
            var parameter = ((Button)sender).DataContext as UploadFileItem;
            var @params = new DialogParameters
            {
                { "data", parameter.Image.Source as BitmapImage },
                { "name", System.IO.Path.GetFileName( parameter.Url) }
            };
            _dialogSvc.ShowDialog(nameof(ImagePreviewer), @params, (r) => { });
        }
    }

    //public class FileUrlToBitmapSourceConverter : IValueConverter
    //{
    //    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    //    {
    //        if(value is UploadFileItem item && !string.IsNullOrWhiteSpace(item.Url))
    //        {
    //            item.Loading = Visibility.Visible;

    //            var stream = CommonUtil.GetImageStreamFromLocalOrHttp(item.Url);

    //            item.Loading = Visibility.Collapsed;

    //            return CommonUtil.CreateBitmapImageFromStream(stream);

    //        }
    //        return null;
    //    }

    //    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    //    {
    //        return null;
    //    }
    //}
}
